package com.fita.wechat.web.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.DateUtils;
import com.fita.entity.agent.Agent;
import com.fita.entity.data.Country;
import com.fita.entity.data.Location;
import com.fita.entity.data.Supplier;
import com.fita.entity.order.Order;
import com.fita.entity.order.OrderSpecialEquipment;
import com.fita.entity.order.OrderStatus;
import com.fita.entity.order.OrderVehicleFee;
import com.fita.entity.set.Set;
import com.fita.wechat.entity.security.Login;
import com.fita.wechat.service.CouponService;
import com.fita.wechat.service.DataService;
import com.fita.wechat.service.OrderService;
import com.fita.wechat.service.SetService;
import com.fita.wechat.web.interceptor.Mobile;
import com.fita.wechat.web.interceptor.Wechat;
import com.fita.wechat.web.resolver.Secure;

/**
 * 
 * @author 宋剑宏
 *
 */
@Controller
public class OrderController {
    private static final Logger logger = LoggerFactory.getLogger(OrderController.class);
    
    @Autowired
    private CouponService couponService;

    @Autowired
    private OrderService orderService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<Agent> agentService;
    

    @Autowired
    @Qualifier("dataService")
    private DataService<Location> locationService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<Supplier> supplierService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<Country> countryService;
    
    @Autowired
    private SetService setService;
    
    /**
     * 根据orderStatus查询订单
     * 
     * @param orderStatus
     * @return
     */
    @Wechat
    @Mobile
    @RequestMapping(value = "/orders", method = RequestMethod.GET)
    public ModelAndView listOrder(@Secure Login login, @RequestParam(name = "status", defaultValue = "PAID") OrderStatus status) {
        
        Agent agent = agentService.load(Agent.class, login.getId());

        OrderStatus status2 = status;

        System.out.println("alias "+status2.getAlias());
        logger.info("status alias is [{}]",status2.getAlias());
        ModelAndView modelAndView = new ModelAndView("order/order-" + status2.getAlias() + "-list");
        
        List<Order> orders = orderService.list(agent, status2);
        
        modelAndView.addObject("orders", orders);
        
        return modelAndView;
    }

    /**
     * 取消预定
     * 
     * @param id
     * @return
     */
    @Wechat
    @Mobile
    @RequestMapping(value = "/orders/{id}/cancel-booking", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult cancelOrderBooking(@PathVariable Long id) {
        HttpResult httpResult = new HttpResult();
        try {
            orderService.cancelBooking(id);
            httpResult.success().message("取消成功");
        } catch (Exception e) {
            logger.error("orderBookingCancel occurs error: ", e);
            httpResult.fail("500").message(e.getMessage());
        }
        return httpResult;
    }

    
    
    /**
     * 立即支付
     * 
     * @param id
     * @return
     */
    @Wechat
    @Mobile
    @RequestMapping(value = "/orders/{id}/pay", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult pay(@PathVariable Long id) {
        HttpResult httpResult = new HttpResult();
        // update order payment status to paid
        try {
            orderService.pay(id);
            httpResult.success().message("支付成功");
        } catch (Exception e) {
            logger.error("orderPay occurs error: ", e);
            httpResult.fail("500").message("支付失败");
        }
        return httpResult;
    }

    /**
     * 取消订单
     * 
     * @param id
     * @return
     */
    @Wechat
    @Mobile
    @RequestMapping(value = "/orders/{orderId}/cancel", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult cancelOrder(@PathVariable(name = "orderId") Long orderId) {
        
        HttpResult httpResult = new HttpResult();
        try {
            orderService.cancelOrder(orderId);
            
            Order order = orderService.load(Order.class, orderId);
            
            if (order.getPayStatus().isPaid()) {
                
                httpResult.success().message("您的订单已取消<br>退款会在5个工作日内原路返还。");
            }else {
                httpResult.success().message("您的订单已取消。");
            }
            
            

    		//优惠券 order 重置为NULL
    		couponService.resetCoupon(order);
            
        } catch (Exception e) {
            
            logger.error("orderCancel occurs error: ", e);
            
            httpResult.fail("500").message(e.getMessage());
        }
        return httpResult;
    }
    
    @Wechat
    @Mobile
    @RequestMapping(value = "/orders/{id}", method = RequestMethod.GET)
    public ModelAndView detail(@PathVariable Long id) {
        ModelAndView modelAndView = new ModelAndView("order/order-detail");
        
        Order order = orderService.load(id);
        modelAndView.addObject("order", order);
        
        Location pickupLocation = locationService.load(Location.class, "code", order.getPickupLocation());
        Location returnLocation = locationService.load(Location.class, "code", order.getReturnLocation());
        modelAndView.addObject("pickupLocation", pickupLocation);
        modelAndView.addObject("returnLocation", returnLocation);
        
        Supplier supplier = supplierService.load(Supplier.class, "code", order.getBrand());
        modelAndView.addObject("supplier", supplier);
        
        Country country = countryService.load(Country.class, "code", order.getCountry());
        modelAndView.addObject("country", country);
        
        Set set = setService.load(order.getDetails().getSetMeal());
        modelAndView.addObject("set", set);
        
        int days = DateUtils.daysBetween(order.getPickupDate(), order.getReturnDate());
        modelAndView.addObject("days", days);
        
        // list order special equipment
        List<OrderSpecialEquipment> equipments = orderService.listSpecialEquipment(order);
        modelAndView.addObject("equipments", equipments);
        
        // list order vehicle fee
        List<OrderVehicleFee> orderVehicleFees = orderService.listVehicleFee(order);
        Map<String, List<OrderVehicleFee>> vehicleFees = CollectionUtils.constructMapValues(orderVehicleFees, "include");
        modelAndView.addObject("include", vehicleFees.get("true"));
        modelAndView.addObject("unInclude", vehicleFees.get("false"));
        
        // TODO load location detail here for order detail
        
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        modelAndView.addObject("dateFormat", dateFormat);
        
        return modelAndView;

    }
}
